enyo.kind({
   name: "PsnTrophies.Friends",
   kind: "enyo.Control",
   classes: "onyx",
   events: { 
      onSelect: ""
   },
   components: [
      {kind: "PsnTrophies.Constants", name: "C"},
      /* NoEnyo {kind: "DbService", dbKind: "psntrophies.friends:1", onFailure: "dbFailure", components: [
         {name: "putKind_Friends", method: "putKind", onSuccess: "putKind_Friends_Success"},
         {name: "put_Friends", method: "put", onSuccess: "put_Friends_Success"},
         {name: "merge_Friend", method: "merge", onSuccess: "merge_Friend_Success"},
         {name: "find_Friends", method: "find", onSuccess: "find_Friends_Success"},
         {name: "del_Friends", method: "del", onSuccess: "del_Friends_Success"}
      ]},*/
      {kind: "onyx.InputDecorator", components: [
         {name: "addPsnIdInput", kind: "onyx.Input", placeholder: "Add PSN ID Here", onchange: "addFriend", defaultFocus: true}
      ]},
      {name: "friendScroller", kind: "enyo.Scroller", horizontal: "auto", vertical: "auto", components: [
         {kind: "onyx.Groupbox", components: [
            {kind: "onyx.GroupboxHeader", content: "All Friends"},
            {name: "friendList", kind: "Repeater", onSetupItem: "getFriendListItem", components: [
               {kind: "onyx.Item", layoutKind: "FittableRowsLayout", style: "border-bottom-style: inset; border-width: 1px; border-color: grey", onclick: "listItemClick", components: [
                  {kind: "Control", layoutKind: "FittableColumnsLayout", components: [
                     {kind: "Control", layoutKind: "FittableRowsLayout", components: [
                        {name: "avatarImage", kind: "Image", style: "width: 50px; height: 50px;"}
                     ]},
                     {kind: "Control", layoutKind: "FittableRowsLayout", fit: true, components: [
                        {name: "psnName", style: "font-size: 100%; font-weight: bold; padding-bottom: 1px; padding-left: 1px"},
                        {kind: "enyo.Control", layoutKind: "FittableColumnsLayout", fit: true, style: "padding-bottom: 1px; padding-left: 1px", components: [
                           {name: "level", style: "font-size: 100%;"},
                           {name: "progress", kind: "onyx.ProgressBar", barClasses: "onyx-dark", fit: true},
                        ]},
                        {kind: "enyo.Control", layoutKind: "FittableColumnsLayout", style: "padding-bottom: 1px; padding-left: 1px", components: [
                           {name: "totalTrophies", style: "font-size: 100%; padding-right:5px;"},
                           {kind: "enyo.Control", layoutKind: "FittableColumnsLayout", components: [
                              {kind: "Control", layoutKind: "FittableRowsLayout", components: [
                                 {name: "bronzeImage", kind: "Image", src: "assets/game-bronze.png"},
                              ]},
                              {name: "bronzeCount"},
                              {kind: "Control", layoutKind: "FittableRowsLayout", components: [
                                 {name: "silverImage", kind: "Image", src: "assets/game-silver.png"},
                              ]},
                              {name: "silverCount"},
                              {kind: "Control", layoutKind: "FittableRowsLayout", components: [
                                 {name: "goldImage", kind: "Image", src: "assets/game-gold.png"},
                              ]},
                              {name: "goldCount"},
                              {kind: "Control", layoutKind: "FittableRowsLayout", components: [
                                 {name: "platinumImage", kind: "Image", src: "assets/game-plat.png"},
                              ]},
                              {name: "platinumCount"}
                           ]}
                        ]}
                     ]}
                  ]}
               ]}
            ]}
         ]}
      ]}
   ],
   create: function() {
      this.inherited(arguments);
      
      // Load common constants
      //const myConstantsObj = new PsnTrophies.Constants();
      //this.log("myConstants loaded: " + enyo.json.stringify(myConstantsObj));
      //var testBefore = myConstantsObj.v("PSN_API_GETPSNID_PREFIX");
      //this.log("testBefore: " + testBefore);
      //myConstantsObj.constants["PSN_API_GETPSNID_PREFIX"] = "brokedItStillz";
      //var testAfter = myConstantsObj.v("PSN_API_GETPSNID_PREFIX");
      //this.log("testAfter: " + testAfter);
      
      // Create Friends DB
      var indexes = [{"name":"psnid", props:[{"name": "psnid"}]},
                     {"name":"state", props:[{"name": "state"}]}];
      // NoEnyo - this.log("enyo.fetchAppId()=" + enyo.fetchAppId())
      // NoEnyo - this.$.putKind_Friends.call({owner: "com.palm.feedreader", indexes:indexes});
      
      // Data for this view
      this.storedPsnIds = [];
      this.serverPsnIdData = {};
      this.psnIdRetries = {};
      
      // NoEnyo - this.$.find_Friends.call({query:{"from":"psntrophies.friends:1"}});
   },
	lookupAllPsnIdDataFromServer: function() {
		this.log("this.storedPsnIds = " + enyo.json.stringify(this.storedPsnIds));
      for (i in this.storedPsnIds) {
			var curPsnId = this.storedPsnIds[i].psnid;
			this.lookupPsnIdDataFromServer(curPsnId);
	  }
	  //if (this.storedPsnIds.length == 0) 
	     //this.$.friendList.render();
	},
	lookupPsnIdDataFromServer: function(psnUserName) {
      this.log("Getting PsnId data for '" + psnUserName + "'");
      var psn_api_getpsnid = this.$.C.v("PSN_API_GETPSNID_PREFIX") + psnUserName;
      var query = "select * from xml where url = \"" + psn_api_getpsnid + "\"";
      var getPsnIdUrl_JsonXform = this.$.C.v("YAHOO_API_PREFIX") + query + this.$.C.v("YAHOO_API_SUFFIX");
      this.log("Getting PsnId with URL: " + getPsnIdUrl_JsonXform);
      this.getPsnIdWebService(getPsnIdUrl_JsonXform);
   },
	getPsnIdWebService: function(psnIdGetUrl) {
	   this.log("Starting enyo ajax call");
	   var request = new enyo.Ajax({
	      url: psnIdGetUrl,
	      method: "GET",
	      handleAs: "json",
	    });
	   request.response(enyo.bind(this, "getPsnIdWebService_Success"));
	   request.fail(enyo.bind(this, "getPsnIdWebService_Failure"))
	   request.go({});
	   this.log("Completed enyo ajax call");
	},
   getPsnIdWebService_Success: function(inSender, inResponse) {
      this.log("inResponse = " + enyo.json.stringify(inResponse));
      
      if (!inResponse.query || !inResponse.query.results || !inResponse.query.results.PSNId) {
         this.log("Empty response received from yahoo for psnid.  Retrying with url: " + inSender.url);
         if (!this.psnIdRetries[inSender.url])
            this.psnIdRetries[inSender.url] = 1;
         else
            this.psnIdRetries[inSender.url] = this.psnIdRetries[inSender.url] + 1;
         if (this.psnIdRetries[inSender.url] <= 3) {
            this.log("Retry count is " + this.psnIdRetries[inSender.url]);
            this.$.getPsnIdWebService.setUrl(inSender.url);
            this.$.getPsnIdWebService.call();
         } else {
            this.log("Retry count is over 3, giving up.");
         }
         return;
      }
      
      var psnid = inResponse.query.results.PSNId;
      this.log("Merging data received from server for PsnId '" + psnid.ID + "' into the database...");
      var friend1 = { _kind: "psntrophies.friends:1", psnid: psnid.ID, avatar: psnid.Avatar, level: psnid.Level, 
            progress: psnid.Progress, totalTrophies: psnid.Trophies.Total, bronzeCount: psnid.Trophies.Bronze,
            silverCount: psnid.Trophies.Silver, goldCount: psnid.Trophies.Gold, platinumCount: psnid.Trophies.Platinum};
      var friends = [friend1];
      this.putOrMergeFriends(friends);
   },
   getPsnIdWebService_Failure: function(inSender, inResponse) {
      this.log(inResponse.error.description);
   },
   getFriendListItem: function(inSender, inEvent) {
      var inIndex = inEvent.index;
      this.log("inIndex is " + inIndex);
      
      if (inIndex < this.storedPsnIds.length) {
         var curPsnAcct = this.storedPsnIds[inIndex];
         if (curPsnAcct) {
            this.log("curPsnAcct is: " + enyo.json.stringify(curPsnAcct));
            var rowControl = inEvent.item;
            this.log("Loading friend '" + curPsnAcct.psnid + "'");
            rowControl.$.avatarImage.setSrc(curPsnAcct.avatar);
            rowControl.$.psnName.setContent(curPsnAcct.psnid);
            rowControl.$.level.setContent("Level: " + curPsnAcct.level);
            rowControl.$.progress.setProgress(curPsnAcct.progress);
            rowControl.$.totalTrophies.setContent("Trophies: (" + curPsnAcct.totalTrophies + ")");
            rowControl.$.bronzeCount.setContent(curPsnAcct.bronzeCount);
            rowControl.$.silverCount.setContent(curPsnAcct.silverCount);
            rowControl.$.goldCount.setContent(curPsnAcct.goldCount);
            rowControl.$.platinumCount.setContent(curPsnAcct.platinumCount);
         }
         return true;
      }
   },
   listItemClick: function(inSender, inEvent) {
      this.log("List item clicked");
      var selectedFriend = this.storedPsnIds[inEvent.index];
      this.log("Selected friend = " + selectedFriend.psnid);
      this.doSelect(selectedFriend);
   },
   putKind_Friends_Success: function(nSender, inResponse) {
      this.log("Created new DB kind: " + enyo.json.stringify(inResponse));
      
      // Load any stored Friends from db8
      this.$.find_Friends.call({query:{"from":"psntrophies.friends:1"}});
   },
   putOrMergeFriends: function(friends) {
      this.log("Friends to put or merge = " + enyo.json.stringify(friends));
      for (i in friends) {
         var query = {"from":"psntrophies.friends:1",
                      "where":[{"prop":"psnid","op":"=","val":"" + friends[i].psnid + ""}]};
         this.putOrMergeFriend(friends[i], query);
      }
   },
   putOrMergeFriend: function(friend, findQuery) {
      this.log("Now creating or updating friend: " + enyo.json.stringify(friend));
      this.log("Query to identify the friend is: " + enyo.json.stringify(findQuery));
      
      // Quick and dirty check for overlap here.  If this needs to be done more 
      // than once, then just construct a PsnIdNameToPsnIdDbObjMap after the initial find.
      var friendAlreadyStored = false;
      for (i in this.storedPsnIds) {
         var storedPsnId = this.storedPsnIds[i];
         this.log("storedPsnId = " + enyo.json.stringify(storedPsnId));
         this.log("Now compariing friend.psnid = " + friend.psnid + " to storedPsnId.psnid = " + storedPsnId.psnid);
         if (friend.psnid.toUpperCase() === storedPsnId.psnid.toUpperCase()) {
            friendAlreadyStored = true;
            break;
         }
      }
      this.log("friendAlreadyStored = " + friendAlreadyStored);
      
      // TODO: Add back DB functionality via PhoneGap or browser cache method.
      // Caleb - 4/8/2012: Skip putting or merging with a DB and...
      /*if (friendAlreadyStored) {
         this.log("This friend does exist, updating...");
         this.$.merge_Friend.call({"query": findQuery, "props": friend});
      } else {
         this.log("This friend does not yet exist, creating...");
         var objs = [friend];
         this.$.put_Friends.call({objects: objs});
      }*/
      // ... instead force all server returned data straight into memory.
      this.storedPsnIds[this.storedPsnIds.length] = friend;
      this.log("Now refreshing the UI with latest friend data...");
      this.$.friendList.setCount(this.storedPsnIds.length);
   },
   put_Friends_Success: function(inSender, inResponse) {
      this.log("Put success, results=" + enyo.json.stringify(inResponse));
      this.log("Refreshing this.storedPsnIds so we pick the just added friend.");
      this.$.find_Friends.call({query:{"from":"psntrophies.friends:1"}});
   },
   find_Friends_Success: function(inSender, inResponse) {
      this.log("inResponse = " + enyo.json.stringify(inResponse));
      this.storedPsnIds = inResponse.results;
      this.log("Now refreshing the UI with the latest from the DB...");
      this.$.friendList.render();
   },
   merge_Friend_Success: function(inSender, inResponse) { 
      this.log("merge success, results=" + enyo.json.stringify(inResponse));
      this.log("Refreshing this.storedPsnIds so we pick the just merged friend.");
      this.$.find_Friends.call({query:{"from":"psntrophies.friends:1"}});
   }, 
   dbFailure: function(inSender, inError, inRequest) {
      this.log("inSender.name = " + inSender.name + " | inError = " + enyo.json.stringify(inError) + " | inRequest = " + inRequest);
   },
   addFriend: function(inSender, inEvent) {
      var screenName = inSender.hasNode().value;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         ;
      this.log("screenName = " + screenName);
      inSender.node.value = "";
      if (screenName != "") {
         this.log("Adding friend with screenName: " + screenName);
         this.lookupPsnIdDataFromServer(screenName);
      }
   },
   deleteFriend: function(inSender, swipedItemIndex) {
      var psnIdToDelete = this.storedPsnIds[swipedItemIndex].psnid;
      this.log("User deleted friend: " + psnIdToDelete);
      var query =  {"query":{"from":"psntrophies.friends:1","where":[{"prop":"psnid","op":"=","val":psnIdToDelete}]}};
      this.$.del_Friends.call(query);
   },
   del_Friends_Success: function(inSender, inResponse) {
      this.log("Deleted friends from local db: " + enyo.json.stringify(inResponse));
      this.$.find_Friends.call({query:{"from":"psntrophies.friends:1"}});
   }
});